package com.song.JavaThread_day02.ch2_8;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Buffer {
	
	
	private LinkedList<String> buffer;
	private int maxSize;
	
	private ReentrantLock lock;
	
	private Condition lines;
	
	private Condition space;
	
	private Boolean pendingLines;

	public Buffer(int maxSize) {
		super();
		this.maxSize = maxSize;
		buffer = new LinkedList<>();
		lock = new ReentrantLock();
		lines = lock.newCondition();
		space = lock.newCondition();
		pendingLines =true;
	}
	
	public void insert(String line)
	{
		lock.lock();
		
		try {
			while(buffer.size() == maxSize)
			{
				space.await();
			}
			buffer.offer(line);
//			System.out.printf(" %s :insert line  %s   buffer size is %d \n",Thread.currentThread().getName(),line,buffer.size());
			lines.signalAll();
			
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
	
	public String get()
	{
		String line =null;
		lock.lock();
		
		try {
			while( (buffer.size()==0) &&(hasPendingLines()))
			{
				lines.await();
			}
			
			if(hasPendingLines())
			{
				line = buffer.poll();
//				System.out.printf(" %s :read line  %s   \n",Thread.currentThread().getName(),line);
				space.signalAll();
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
		
		return line;
	}
	
	public void setPendingLines(boolean pendingLines)
	{
		this.pendingLines = pendingLines;
	}
	
	public boolean hasPendingLines()
	{
		return pendingLines || buffer.size()>0;
	}
}
